#ifndef __HASHUTIL_H__
#define __HASHUTIL_H__

#include <openssl/evp.h>
#include <string>
#include <vector>
#include <sstream>
#include <iomanip>
#include <stdexcept>

class HashUtil {
public:
    // 通用哈希函数：传入算法名（"SHA256"、"SHA512"、"MD5" 等）
    static std::string compute(const std::vector<unsigned char>& data, const std::string& algo = "SHA256") {
        const EVP_MD* md = EVP_get_digestbyname(algo.c_str());
        if (!md) {
            throw std::runtime_error("Unsupported hash algorithm: " + algo);
        }

        EVP_MD_CTX* ctx = EVP_MD_CTX_new();
        if (!ctx) {
            throw std::runtime_error("EVP_MD_CTX_new failed");
        }

        unsigned char hash[EVP_MAX_MD_SIZE];
        unsigned int length = 0;

        if (EVP_DigestInit_ex(ctx, md, nullptr) != 1 ||
            EVP_DigestUpdate(ctx, data.data(), data.size()) != 1 ||
            EVP_DigestFinal_ex(ctx, hash, &length) != 1) {
            EVP_MD_CTX_free(ctx);
            throw std::runtime_error("EVP digest calculation failed");
        }

        EVP_MD_CTX_free(ctx);

        std::ostringstream oss;
        for (unsigned int i = 0; i < length; i++) {
            oss << std::hex << std::setw(2) << std::setfill('0') << (int)hash[i];
        }
        return oss.str();
    }

    // 针对 std::string 的重载
    static std::string compute(const std::string& content, const std::string& algo = "SHA256") {
        return compute(std::vector<unsigned char>(content.begin(), content.end()), algo);
    }
};



#endif